<!DOCTYPE HTML>
<html>
<head>
<script src="../resources/js-test.js"></script>
<style>
    .test {
        content: "UNTOUCHED";
    }

    @supports (display: none) {
        #t0 { content: "APPLIED" }
    }

    @supports (display: deadbeef) {
        #t1 { content: "FAIL" }
    }

    /* Negation */
    @supports not (display: deadbeef) {
        #t2 { content: "APPLIED" }
    }

    @supports not (display: none) {
        #t3 { content: "FAIL" }
    }

    @supports not (not (display: none)) {
        #t4 { content: "APPLIED" }
    }

    @supports not (not (not (display: none))) {
        #t5 { content: "FAIL" }
    }

    /* Conjunction */
    @supports (display: none) and (display: block) {
        #t6 { content: "APPLIED" }
    }

    @supports (display: none) and (display: block) and (display: inline) {
        #t7 { content: "APPLIED" }
    }

    @supports (display: none) and (display: block) and (display: deadbeef) and (display: inline) {
        #t8 { content: "FAIL" }
    }

    /* Disjunction */
    @supports (display: none) or (display: inline) {
        #t9 { content: "APPLIED" }
    }

    @supports (display: none) or (display: block) or (display: inline) {
        #t10 { content: "APPLIED" }
    }

    @supports (display: none) or (display: deadbeef) or (display: inline) {
        #t11 { content: "APPLIED" }
    }

    @supports (display: ohhai) or (display: deadbeef) or (display: rainbows) {
        #t12 { content: "FAIL" }
    }

    /* Bad syntax. Can't mix operators without a layer of parentheses. */
    @supports (display: none) and (display: block) or (display: inline) {
        #t13 { content: "FAIL" }
    }

    @supports not (display: deadbeef) and (display: block) {
        #t14 { content: "FAIL" }
    }

    /* Mix 'n match */
    @supports (not (border: 1px 1px 1px 1px 1px solid #000)) and (display: block) {
        #t15 { content: "APPLIED" }
    }

    @supports (display: block !important) and ((display: inline) or (display: deadbeef)){
        #t16 { content: "APPLIED" }
    }

    @supports not ((not (display: block)) or ((display: none) and (deadbeef: 1px))) {
        #t17 { content: "APPLIED" }
    }

    /* Whitespace/Syntax */
    @supports not( display: deadbeef) {
        #t22 { content: "APPLIED" }
    }

    @supports (display: none)and (   -webkit-transition: all 1s ) {
        #t23 { content: "APPLIED" }
    }

    @supports (display: none)or(-webkit-transition: all 1s) {
        #t24 { content: "APPLIED" }
    }

    @supports (display: none) or(-webkit-transition: all 1s    ) {
        #t25 { content: "APPLIED" }
    }

    @supports (((((((display: none))))))) {
        #t26 { content: "APPLIED" }
    }

    @supports(((((((display: none))))))) {
        #t27 { content: "APPLIED" }
    }

    @supports (!important) {
        #t28 { content: "FAIL" }
    }

    @supports not not not not (display: none) {
        #t29 { content: "FAIL" }
    }

    /* Functions */

    @supports (top: -webkit-calc(80% - 20px)) {
        #t30 { content: "APPLIED" }
    }

    @supports (background-color: rgb(0, 128, 0)) {
        #t31 { content: "APPLIED" }
    }

    @supports (background: url("/blah")) {
        #t32 { content: "APPLIED" }
    }

    @supports ((top: -webkit-calc(80% - 20px)) and (not (background-color: rgb(0, 128, 0)))) or (background: url("/blah")) {
        #t33 { content: "APPLIED" }
    }

    @supports (background: invalid("/blah")) {
        #t34 { content: "FAIL" }
    }

    /* Nesting. */
    @supports (display: none) {
        @supports (display: deadbeef) {
            #t18 { content: "FAIL" }
        }
        @supports (display: inline) {
            #t19 { content: "APPLIED" }
        }
        @supports (display: inline) {
        }
        @media all {
            #t20 { content: "APPLIED" }
            @supports (display: inline) {
                #t21 { content: "APPLIED" }
            }
        }
    }

    @media all {
        @supports (display: inline) {
            @media all {
                @supports (display: none) {
                    #t35 { content: "APPLIED" }
                }
            }
        }
    }

    @media not all {
        @supports (display: none) {
            #t36 { content: "FAIL" }
        }
    }

    /* Invalid syntax error recovery */

    @supports (display: none);
    @supports (display: none) and ( (display: none) ) {
        #t37 { content: "APPLIED" }
    }

    @supports (display: none)) ;
    @supports (display: none) {
        #t38 { content: "APPLIED" }
    }

    @supports;
    @supports (display: none) {
        #t39 { content: "APPLIED" }
    }

    @supports ;
    @supports (display: none) {
        #t40 { content: "APPLIED" }
    }

    @supports (display: none)) {
        #t41 { content: "FAIL" }
    }
    @supports (display: none) {
        #t41 { content: "APPLIED" }
    }

    @supports (display: )) {
        #t42 { content: "FAIL" }
    }
    @supports (display: none) {
        #t42 { content: "APPLIED" }
    }

    @supports ((display: none) and {
        #t43 { content: "FAIL" }
    }
    @supports (display: none) {
        #t43 { content: "FAIL" }
    }
    );

    @supports ((display: none) and ;
    @supports (display: none) {
        #t44 { content: "FAIL" }
    }
    );

    @supports (#(display: none) {}
        #t45 { content: "FAIL" }
    );

    @supports ((display: none#) {}
        #t46 { content: "FAIL" }
    );

    @supports (#) or (display: none) {
        #t47 { content: "APPLIED"; }
    }

</style>
</head>
<body>
<div id="test_container"></div>

<script>
    description("Test the @supports rule.");
    var numTests = 48;
    var untouchedTests = [1, 3, 5, 8, 12, 13, 14, 18, 28, 29, 34, 36, 43, 44, 45, 46]; // Tests whose content shouldn't change from the UNTOUCHED default.

    var container = document.getElementById("test_container");
    for (var i=0; i < numTests; i++) {
        var div = document.createElement("div");
        div.id = "t" + i;
        div.className = "test";
        container.appendChild(div);
        shouldBeEqualToString("getComputedStyle(document.getElementById('t"+i+"')).content", untouchedTests.indexOf(i) >= 0 ? "UNTOUCHED" : "APPLIED");
    }

    test_container.parentNode.removeChild(test_container);
</script>
</body>
</html>
